package com.carsa.blackberry.util.ui;

import java.util.Enumeration;
import java.util.Vector;

import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.MainScreen;

import com.carsa.blackberry.ui.UIKeys;
import com.carsa.blackberry.util.ui.widget.GridFieldManager;

/**
 * @author Nahuel Barrios.
 * @since 20/07/2010.
 * @version 1.0
 */
public class UIUtil {

    /**
     * @param data
     * @return
     */
    public static GridFieldManager loadHeadersToGrid(GridFieldManager aGrid, Field[] data) {
	Vector dataVector = new Vector(data.length);
	dataVector.addElement(data);

	return loadFieldGridFrom(aGrid, dataVector);
    }

    /**
     * Carga una grilla en base al Vector data que contiene un elemento por cada fila de la grilla, donde cada elemento
     * es un Field[] que contiene cada Field a mostrar en cada columna de la grilla.
     * 
     * @param aGrid
     * @param data
     * @return
     */
    public static GridFieldManager loadFieldGridFrom(GridFieldManager aGrid, Vector data) {
	if (data == null || data.isEmpty())
	    return null;

	if (aGrid == null)
	    return null;

	Enumeration elements = data.elements();
	while (elements.hasMoreElements()) {
	    Field[] fields = (Field[]) elements.nextElement();

	    for (int idx = 0; idx < aGrid.getColumns(); idx++)
		aGrid.add(fields[idx]);

	    for (int idx = 0; idx < aGrid.getColumns(); idx++)
		aGrid.add(new SeparatorField());
	}

	return aGrid;
    }

    /**
     * Preparo los headers para una grilla, se le aplica un formato de texto y retorno el Field[] necesario.
     * 
     * @param headers
     *            Un Vector con los {@link String} de los headers.
     * @param parent
     * @return
     */
    public static Field[] prepareHeadersForGrid(Vector headers, MainScreen parent) {
	Field[] fields = new Field[headers.size()];

	Enumeration elements = headers.elements();
	for (int i = 0; elements.hasMoreElements(); i++) {
	    LabelField lbl_header = new LabelField((String) elements.nextElement(), Field.FIELD_HCENTER
		    | Field.NON_FOCUSABLE);
	    lbl_header.setFont(parent.getFont().getFontFamily()
		    .getFont(Font.ITALIC, UIKeys.SIZE_FOR_TABLE_HEADERS_FONT));
	    fields[i] = lbl_header;
	}

	return fields;
    }

    /**
     * Obtiene la fuente utilizada en el parametro screen y la devuelve pero en el tama�o que indicamos mediante el
     * parametro fontSize
     * 
     * @param screen
     * @param fontSize
     *            El tamaño de la fuente que quiero obtener.
     * @return
     */
    public static Font getFontAtSize(MainScreen screen, int fontSize) {
	if (screen == null)
	    return null;

	return screen.getFont().getFontFamily().getFont(Font.PLAIN, fontSize);
    }

    /**
     * Retorna una nueva fuente con el tamaño especificado en fontSize, a partir de la fuente que le pasamos en aFont
     * 
     * @param aFont
     *            La fuente que se va a modificar.
     * @param fontSize
     *            El tamaño de la fuente que quiero obtener.
     * @return
     */
    public static Font getFontAtSize(Font aFont, int fontSize) {
	if (aFont == null)
	    return null;

	return aFont.getFontFamily().getFont(Font.PLAIN, fontSize);
    }

    /**
     * @param fields
     * @param iFontSize
     * @return
     */
    public static Field[] setFontSize(Field[] fields, int iFontSize) {
	if (fields == null)
	    return null;

	for (int idx = 0; idx < fields.length; idx++)
	    fields[idx].setFont(getFontAtSize(fields[idx].getFont(), iFontSize));

	return fields;
    }

    /**
     * Inserta una linea en blanco en la screen que le pasamos como parametro.
     * 
     * @param aScreen
     * @return false cuando aScreen sea null. true cuando se pueda agregar la linea OK.
     */
    public static boolean addNewEmptyLine(MainScreen aScreen) {
	if (aScreen == null)
	    return false;

	aScreen.add(new LabelField("")); /* It's an empty line */
	return true;
    }

    /**
     * @return Retorna un Field que deja un renglon en blanco.
     */
    public static Field getEmptyLine() {
	return new LabelField(""); /* It's an empty line */
    }

    /**
     * @return Un Field que deja un renglon en blanco, y que a la vez utiliza el maximo disponible de pantalla. Es
     *         decir, utiliza el maximo del dispositivo entonces redimensiona el tama�o de su padre.
     */
    public static GridFieldManager getEmptyLineForResize() {
	GridFieldManager aGrid = new GridFieldManager(1, 0);
	aGrid.add(new LabelField());
	return aGrid;
    }

    /**
     * @param numberOfLines
     *            Las N lineas que queremos dejar en blanco.
     * @return un Field que deja numberOfLines renglon en blanco, y que a la vez utiliza el maximo disponible de
     *         pantalla. Es decir, utiliza el maximo del dispositivo entonces redimensiona el tama�o de su padre.
     */
    public static GridFieldManager getEmptyLineForResize(int numberOfLines) {
	GridFieldManager aGrid = new GridFieldManager(1, 0);
	for (int idx = 0; idx < numberOfLines; idx++)
	    aGrid.add(new LabelField());

	return aGrid;
    }

    // /**
    // * @param numberOfLines La cantidad de renglones en blanco que queremos
    // dejar.
    // * @return Retorna un Field[] que deja numberOfLines renglones en blanco.
    // */
    // public static Field[] getEmptyLine(int numberOfLines){
    // Field[] fields= new Field[numberOfLines];
    //		
    // for (int idx = 0; idx < numberOfLines; idx++)
    // fields[idx]= new LabelField(""); /* It's an empty line */
    //		
    // return fields;
    // }

    /**
     * Inserta numberOfLines lineas en blanco en la screen que le pasamos como parametro.
     * 
     * @param aScreen
     * @param numberOfLines
     * @return false cuando aScreen sea null, o numberOfLines sea menor o igual a cero. true cuando se pueda agregar la
     *         linea OK.
     */
    public static boolean addNewEmptyLine(Manager aScreen, int numberOfLines) {
	if (aScreen == null || numberOfLines <= 0)
	    return false;

	for (int idx = 0; idx < numberOfLines; idx++)
	    aScreen.add(new LabelField("")); /* It's an empty line */
	return true;
    }

    /**
     * Agrega un boton de volver a la screen aScreen que le pasamos como parametro.
     * 
     * @param aScreen
     * @return
     */
    public static boolean addBackButton(final MainScreen aScreen) {
	if (aScreen == null)
	    return false;

	ButtonField bf_back = new ButtonField(UIKeys.TITLE_VOLVER, Field.FIELD_RIGHT);
	bf_back.setChangeListener(new FieldChangeListener() {
	    public void fieldChanged(Field field, int context) {
		UiApplication.getUiApplication().popScreen(aScreen);
	    }
	});

	aScreen.add(bf_back);

	return true;
    }

    /**
     * Prepara la informacion contenida en el Vector data (cada elemento del vector es a su vez un vector que se
     * mapearia con cada columna de la tabla que queremos generar. Este vector contiene los N elementos Field listos
     * para mostrar en la tabla.
     * 
     * @param data
     * @param numberOfColumns
     * @return
     */
    public static Vector prepareDataForTable(Vector data, int numberOfColumns) {

	Vector[] columns = new Vector[numberOfColumns];
	for (int i = 0; i < numberOfColumns; i++)
	    columns[i] = new Vector();

	Enumeration elements = data.elements();
	while (elements.hasMoreElements()) {

	    Field[] aRow = (Field[]) elements.nextElement();

	    for (int i = 0; i < numberOfColumns; i++) {
		((Vector) columns[i]).addElement(aRow[i]);
	    }

	}

	Vector ret = new Vector();
	for (int i = 0; i < numberOfColumns; i++) {
	    ret.addElement((Vector) columns[i]);
	}

	return ret;
    }

}
